﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Smatime.Web.Models;

namespace Smatime.Web.DAO
{
    public interface IBaseAdapter<TTable> : IDisposable
    {
        TTable GetData();
        TTable GetDataBy(long id);
        int Update(TTable table);
    }


    /// <summary>
    ///     Generic implementation of a repository
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="TAdapter"></typeparam>
    public abstract class BaseRepository<T, TTable, TAdapter>
        where T : BaseEntity, new()
        where TAdapter : IBaseAdapter<TTable>, new()
        where TTable : DataTable, new()
    {
        /// <summary>
        ///     Get company store list
        /// </summary>
        /// <returns></returns>
        public virtual IEnumerable<T> GetList()
        {
            using (var adapter = new TAdapter())
            {
                using (var table = adapter.GetData())
                {
                    return table.Rows.Cast<DataRow>()
                        .Select(row => { return (T)(new T().FromDataRow(row)); });
                }
            }
        }

        /// <summary>
        ///     Return the company store by ID
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual T GetById(long id)
        {
            using (var adapter = new TAdapter())
            {
                using (var table = adapter.GetDataBy(id))
                {
                    var row = table.Rows[0];
                    return (T)(new T().FromDataRow(row));
                }
            }
        }

        //<summary>
        //update new record to database
        //</summary>
        //<param name="obj"></param>
        public virtual void Update(T obj)
        {
            using (var adapter = new TAdapter())
            {
                using (var table = adapter.GetDataBy(obj.Id))
                {
                    var row = table.Rows[0];
                    obj.ToDataRow(row);
                    adapter.Update(table);
                }
            }
        }

        /// <summary>
        ///     insert new record to database
        /// </summary>
        /// <param name="obj"></param>
        public void Insert(T obj)
        {
            using (var adapter = new TAdapter())
            {
                using (var table = new TTable())
                {
                    var row = table.NewRow();
                    obj.ToDataRow(row);
                    table.Rows.Add(row);
                    adapter.Update(table);
                }
            }
        }

        public void Delete(long id)
        {
            using (var adapter = new TAdapter())
            {
                using (var table = adapter.GetDataBy(id))
                {
                    var row = table.Rows[0];
                    row.Delete();
                    //table.Rows.Remove(row);
                    adapter.Update(table);
                }
            }
        }
    }
}